//
//  RAYUploader.m
//  hooray
//
//  Created by wbxiaowangzi on 16/4/14.
//  Copyright © 2016年 RAY. All rights reserved.
//

#import "RAYUploader.h"
#import "QNResolver.h"
#import "QNDnsManager.h"
#import "QNNetworkInfo.h"

//#import "RAYHttpAPI.h"
//#import "RAYHttpURL.h"
//#import "RAYHttpAPI+RequestDataManager.h"

@interface RAYUploader ()
@property (nonatomic, strong) QNUploadManager *upmanager;
@property (nonatomic, strong) NSMutableDictionary *flagDic;
@property (nonatomic, strong) NSMutableArray *uploadTaskArr;
@property (nonatomic, strong) NSMutableDictionary *uploadingTaskDic;

@end


@implementation RAYUploader

+(instancetype)defaultUploader{
    
//    static RAYUploader *uploader= nil;
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        uploader = [[self alloc]init];
//    });
//    return uploader;
    
    RAYUploader * uploader = [[RAYUploader alloc] init];
    return uploader;
}
- (void)uploadWithFileurl:(NSURL *)fileurl {
    
}
- (void)uploadWithFile:(id)sender type:(NSInteger)type index:(RAYUploaderIndex)index {
    //请求token、key
    [MYAFNetworking POST:URL_QiNiu_Token parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        if ([responseObject[@"code"] isEqualToString:@"200"]) {
            NSString *token = responseObject[@"data"][@"token"];
            
            QNConfiguration *config =[QNConfiguration build:^(QNConfigurationBuilder *builder) {
                NSMutableArray *array = [[NSMutableArray alloc] init];
                [array addObject:[QNResolver systemResolver]];
                QNDnsManager *dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
                //是否选择  https  上传
                builder.zone = [[QNAutoZone alloc] initWithDns:dns];
                //设置断点续传
                NSError *error;
                builder.recorder = [QNFileRecorder fileRecorderWithFolder:@"保存目录" error:&error];
            }];
            QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config];
            // 上传进度
            QNUploadOption *uploadOption = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) {
                NSLog(@"percent == %.2f", percent);
            }
                                                                         params:nil
                                                                       checkCrc:NO
                                                             cancellationSignal:nil];
            
            self.fileType = type;
            self.uploaderIndex = index;
            if (type == 0 || type == 2) {
                NSString *filePath = [self getImagePath:sender];
                [upManager putFile:filePath key:nil token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
                    NSLog(@"info ===== %@", info);
                    NSLog(@"resp ===== %@", resp);
                    [self uploadWithQNResponseInfo:info key:key resp:resp fileUrl:nil];
                }
                            option:uploadOption];
            } else if (type == 1) {
//                ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
                
                [self.lib assetForURL:sender resultBlock:^(ALAsset *asset) {
                    [upManager putALAsset:asset key:nil token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
                        NSLog(@"info ===== %@", info);
                        NSLog(@"resp ===== %@", resp);
                        [self uploadWithQNResponseInfo:info key:key resp:resp fileUrl:nil];
                    } option:uploadOption];
                } failureBlock:^(NSError *error) {
                    
                }];
            }            
        } else {
            if ([self.delegate respondsToSelector:@selector(uploadError:)]) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.delegate uploadError:nil];
                });
            }else{
                NSLog(@"WORNING: 代理方法：(uploadError:)未实现");
            }
            [MBProgressHUD myShowHUDAddedTo:nil labelText:@"上传失败" animated:YES];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
        if ([self.delegate respondsToSelector:@selector(uploadError:)]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate uploadError:error];
            });
        }else{
            NSLog(@"WORNING: 代理方法：(uploadError:)未实现");
        }
        [MBProgressHUD myShowHUDAddedTo:nil labelText:@"上传失败" animated:YES];
    }];
}

- (void)uploadWithFileurl:(NSURL *)fileurl bucketType:(NSString *)bucket{
    
    if ([self fileWithFileUrl:fileurl]) {
        //任务已经存在 继续上传
        [self continueUploadWithFileUrl:fileurl];
        return;
    }
    //请求token、key
    [MYAFNetworking POST:URL_QiNiu_Token parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        if ([responseObject[@"code"] isEqualToString:@"200"]) {
            NSString *token = [responseObject objectForKey:@"token"];
//            NSString *filenameOnQiniu = [fileurl pathExtension];
            
            [self uploadDataWithFileUrl:fileurl withKey:nil token:token];
            RAYUploadFile *file = [[RAYUploadFile alloc]init];
            file.fileurl = fileurl;
            file.key = nil;
            file.token = token;
            //加入到任务数组中
            [self.uploadTaskArr addObject:file];
        } else {
            if ([self.delegate respondsToSelector:@selector(uploadError:)]) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.delegate uploadError:nil];
                });
            }else{
                NSLog(@"WORNING: 代理方法：(uploadError:)未实现");
            }
            [MBProgressHUD myShowHUDAddedTo:nil labelText:@"上传失败" animated:YES];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
        if ([self.delegate respondsToSelector:@selector(uploadError:)]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate uploadError:error];
            });
        }else{
            NSLog(@"WORNING: 代理方法：(uploadError:)未实现");
        }
        [MBProgressHUD myShowHUDAddedTo:nil labelText:@"上传失败" animated:YES];
    }];
//    [[RAYHttpAPI defaultAPI] get:RAYHttpPathQiniuToken
//                   urlParameters:@{@"bucket":bucket,
//                                   @"extname":[fileurl pathExtension],
//                                   @"from":@"ios"
//                                   }
//               completionHandler:^(id jsonObject, NSError *error) {
//                   if ([RAYHttpAPI dealWithError:error StatueCode:jsonObject]) {
//                       return ;
//                   }
//                   NSDictionary *dataDic = jsonObject[@"data"];
//                   NSString *token = [dataDic objectForKey:@"token"];
//                   NSString *filenameOnQiniu = [dataDic objectForKey:@"filename"];
//                   [self uploadDataWithFileUrl:fileurl withKey:filenameOnQiniu token:token];
//                   
//                   RAYUploadFile *file = [[RAYUploadFile alloc]init];
//                   file.fileurl = fileurl;
//                   file.key = filenameOnQiniu;
//                   file.token = token;
//                   //加入到任务数组中
//                   [self.uploadTaskArr addObject:file];
//               }];

}

- (void)uploadDataWithFileUrl:(NSURL *)fileUrl
                      withKey:(NSString *)key
                        token:(NSString *)token{
    [self uploadObject:fileUrl withKey:key token:token];

}

- (void)uploadObject:(NSURL*)fileurl
             withKey:(NSString *)key
               token:(NSString *)token{
    
    [self.flagDic setValue:@(0) forKey:fileurl.path];
    //option
    QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:nil progressHandler: ^(NSString *key, float percent) {
        [self.uploadingTaskDic setObject:@(percent) forKey:fileurl.path];
        if (percent >= 1) {
            [self.flagDic setValue:@(1) forKey:fileurl.path];
            [self.flagDic removeObjectForKey:fileurl.path];
            [self removeTaskWithFileurl:fileurl];
            //[self.uploadingTaskDic removeObjectForKey:fileurl.path];

            if ([self.delegate respondsToSelector:@selector(uploadFinish)]) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.delegate uploadFinish];
                });
            }else{
                NSLog(@"WORNING: 代理方法：(uploadFinish)未实现");
            }
        }
        // NSLog(@"---***---上传进度：%f-----*",percent);
        if ([self.delegate respondsToSelector:@selector(uploadingProgress:fileUrl:)]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate uploadingProgress:percent fileUrl:fileurl];
            });
        }else{
            NSLog(@"WORNING: 代理方法：(uploadingProgress:fileUrl:)未实现");
        }

    } params:nil checkCrc:NO cancellationSignal: ^BOOL () {
        return [[self.flagDic objectForKey:fileurl.path]boolValue];
    }];
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    
    if ([fileurl isKindOfClass:[NSURL class]]) {
        
        [self.upmanager putFile:[(NSURL*)fileurl path]
                            key:key
                          token:token
                       complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
                           [self uploadWithQNResponseInfo:info key:key resp:resp fileUrl:fileurl];
                       } option:opt];
    }
}

- (void)uploadWithQNResponseInfo:(QNResponseInfo*)info key:(NSString *)key resp:(NSDictionary *)resp fileUrl:url{
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    if ([self.delegate respondsToSelector:@selector(uploadWithQNResponseInfo:fileUrl:resp:type:index:)]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.delegate uploadWithQNResponseInfo:info
                                            fileUrl:url
                                               resp:resp
                                               type:self.fileType
                                              index:self.uploaderIndex];
        });
        
    }else{
        NSLog(@"WORNING: 代理方法：(uploadWithQNResponseInfo:fileUrl:resp:type:index: )未实现");
    }
}

//lazy upmanager
-(QNUploadManager *)upmanager{
    if (_upmanager==nil) {
        NSError *error = nil;
        QNFileRecorder *recorder = [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"RAYUploadFileRecord"] error:&error];
        _upmanager = [[QNUploadManager alloc]initWithRecorder:recorder];
    }
    return _upmanager;
}

-(NSMutableDictionary *)flagDic{
    if (_flagDic == nil) {
        _flagDic = [[NSMutableDictionary alloc]init];
    }
    return _flagDic;
}

-(NSMutableArray *)uploadTaskArr{
    if (_uploadTaskArr == nil) {
        _uploadTaskArr = [[NSMutableArray alloc]init];
    }
    return _uploadTaskArr;
}

-(NSMutableDictionary *)uploadingTaskDic{
    if (_uploadingTaskDic == nil) {
        _uploadingTaskDic = [[NSMutableDictionary alloc]init];
    }
    return _uploadingTaskDic;
}

//取消上传
- (void)cancelUploadWithFileUrl:(NSURL *)url{
    [self.flagDic setObject:@1 forKey:url.path];
}

//取消所有上传
- (void)cancelAllTask{
    for (NSString *key in self.flagDic.allKeys) {
        [self.flagDic setObject:@1 forKey:key];
    }

}

//继续上传
- (void)continueUploadWithFileUrl:(NSURL *)url{
    [self.flagDic setObject:@0 forKey:url.path];
    RAYUploadFile *file = [self fileWithFileUrl:url];
    if (file == nil) {
        return;
    }
    NSLog(@"继续上传%@,%@",file.key,file.token);
    [self uploadObject:file.fileurl withKey:file.key token:file.token];
}

- (void)continueAllTask{
    for (NSString *key in self.flagDic.allKeys) {
        NSURL *url = [NSURL fileURLWithPath:key];
        [self continueUploadWithFileUrl:url];
    }

}

- (RAYUploadFile*)fileWithFileUrl:(NSURL*)url{

    for (RAYUploadFile *file in self.uploadTaskArr) {
        if ([file.fileurl isEqual:url]) {
            return file;
        }
    }
    NSLog(@"Error：任务不存在或已经结束");
    return nil;
}

- (void)removeTaskWithFileurl:(NSURL *)url{
    RAYUploadFile *file = [self fileWithFileUrl:url];
    if (file == nil) {
        return;
    }
    [self.uploadTaskArr removeObject:file];
}

- (float)uploadPersentOfFileUrl:(NSURL *)fileUrl{
    NSNumber *persent = [self.uploadingTaskDic objectForKey:fileUrl.path];
    return persent.floatValue;
}

- (BOOL)isUploadingOfFileurl:(NSURL *)fileUrl{
    if ([[self.flagDic objectForKey:fileUrl.path] isEqual:@0]) {
        return YES;
    }
    return NO;
}

//照片获取本地路径转换
- (NSString *)getImagePath:(UIImage *)Image {
    NSString *filePath = nil;
    NSData *data = nil;
    if (UIImagePNGRepresentation(Image) == nil) {
        data = UIImageJPEGRepresentation(Image, 1.0);
    } else {
        data = UIImagePNGRepresentation(Image);
    }
    
    //图片保存的路径
    //这里将图片放在沙盒的Library文件夹中
    NSString *LibraryPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"];
    
    //文件管理器
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    //把刚刚图片转换的data对象拷贝至沙盒中
    [fileManager createDirectoryAtPath:LibraryPath withIntermediateDirectories:YES attributes:nil error:nil];
    NSString *ImagePath = [[NSString alloc] initWithFormat:@"/theFirstImage.png"];
    [fileManager createFileAtPath:[LibraryPath stringByAppendingString:ImagePath] contents:data attributes:nil];
    
    //得到选择后沙盒中图片的完整路径
    filePath = [[NSString alloc] initWithFormat:@"%@%@", LibraryPath, ImagePath];
    return filePath;
}

@end




